package com.booter.common;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public abstract class JsonUtil {

    private static Logger logger = LoggerFactory.getLogger(JsonUtil.class);

    private static ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.registerModule(new AfterburnerModule());
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static ObjectMapper build() {
        return mapper;
    }
//    JsonNode rootNode = mapper.readTree(requestStr); //获得根节点
//    JsonNode txnType = rootNode.get("txnType"); //获得某个json字段
//    String result = txnType.asText(); //获得它的值

    public void readJson(String str) throws JsonProcessingException {
        try {

//            一、通过json转jsonNode
            // JsonNode对象不可变，不能直接构建JsonNode实例的对象图，可以创建JsonNode的子类ObjectNode实例的对象图。
            // 作为JsonNode的子类，ObjectNode可以在任何使用了JsonNode之处使用
//            JsonNode root = mapper.readTree(str);
//            二、createObjectNode实际返回的是一个ObjectNode对象，因为该对象是JsonNode的子类，所以可以自动转换
//          ObjectNode node = mapper.createObjectNode();
            JsonNode root = mapper.createObjectNode();
//            三、通过JsonNodeFactory工厂方式创建
//           JsonNode node = JsonNodeFactory.instance.objectNode();
//            四、对象转为JsonNode
//          mapper.valueToTree(obj);
//            五、at方法可以在给定JsonNode作为根节点Json对象图中访问任何字段。
//            root.at("/node/name");//json路径
//            root.at("/0/id")；//存在json数组时使用索引下标访问json对象
//            六、JsonNode转对象,convertValue与treeToValue转换效果一样,区别convertValue适用范围更光，treeToValue只能接收jsonNode
//          mapper.convertValue(jsonNode, T.class);
//          mapper.treeToValue(jsonNode, T.class);

//            七、通过JsonParser间接转换,需要先将Json Node对象转为JsonParser，然后再从JsonParser中读取对象的数据；它和jsonNode的功能有点类似，只是JsonNode用的比较多，因为Jsonparser比较偏底层，会复杂一点；
//            JsonParser jsonParser = objectMapper.treeAsTokens(treeNode);
//            objectMapper.readValue(jsonParser, T.class);

        } catch (Exception ex) {

        }


    }


    public static byte[] writeValueAsBytes(Object o) {
        try {
            return mapper.writeValueAsBytes(o);
        } catch (Exception ex) {
            logger.error("To json bytes", ex);
            return null;
        }
    }


    public static String toJsonString(Object o) {
        if (o == null) {
            return "";
        }
        try {
            return mapper.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            logger.error("To json error", e);
        }
        return null;
    }


    public static <T> T convertValue(Object value, Class<T> type) {
        try {

            return mapper.convertValue(value, type);
        } catch (Exception ex) {
            logger.error("Convert value error", ex);
        }
        return null;
    }

    public static <T> T convertValue(Object value, TypeReference<T> type) {
        try {
            return mapper.convertValue(value, type);
        } catch (Exception ex) {
            logger.error("Convert value error", ex);
        }
        return null;
    }

    public static <T> T toBean(String str, Class<T> cls) {
        try {
            return mapper.readValue(str, cls);
        } catch (IOException e) {
            logger.error("convert error", e);
        }
        return null;
    }


    public static void main(String[] args) throws Exception {
        String s = "[{\"id\":149,\"title\":\"测试专栏222详情\",\"funds\":\"F001917,F005313\",\"text\":\"测试视频\",\"category\":2,\"duration\":0,\"order\":0,\"fund_cards\":null,\"original_id\":40,\"original_name\":\"测试专栏22\",\"filename\":\"https://xueqiu.feishu.cn/wiki/F7GdwHxnDiLE5kkJZxScL2monQd\",\"media_size\":0,\"updated_by\":\"lichunwen\",\"update_time\":1705476227936,\"publish_time\":1705476227936,\"cover_pic\":null,\"original_cover_pic\":\"https://xqimg.imedao.com/18d161a42b24cd3fef495a8d.png\",\"state\":1,\"content_url\":null,\"business_type\":2,\"publish_day\":20240117}]";
        List<Map<String, Object>> list = toBean2(s, List.class);
        System.out.println(list);

//        JsonNode node = mapper.readTree(s);
//        System.out.println(node.at("/0/id"));
    }


    public static <T> T toBean2(String str, Class<T> cls) {
        try {
            return toBean(str, new CustomizedTypeReference<T>(cls) {
            });
        } catch (Exception e) {
            logger.error("convert error", e);
        }
        return null;
    }


    public static <T> T toBean(String str, TypeReference<T> type) {
        try {
            return mapper.readValue(str, type);
        } catch (IOException e) {
            logger.error("convert error", e);
        }
        return null;
    }


    public static JsonNode toJsonNode(String json) {
        try {
            return mapper.readTree(json);
        } catch (Exception ex) {
            logger.error("convert error", ex);
        }
        return null;
    }

}